/**
 * 工具代码
 */
(function (G, doc) {
  const utils = {
    // 设置字段排序
    setTreeSort: function (columns) {
      let sortValue = 1;
      const _walk = function (data) {
        for (let i = 0; i < data.length; i++) {
          data[i].sort = sortValue++;
          if (data[i].children) {
            data[i].hasChildren = true
            _walk(data[i].children);
          }
        }
      }
      _walk(columns)
      return columns;
    },

    /**
     * 获取合并列的数量
     * @param {*} data 
     * @returns 
     */
    getColumnCount(data) {
      let count = 0;
      if (!data) return count;
      const { children } = data;
      if (!children) return count;
      for (let i = 0, len = children.length; i < len; i++) {
        count += children[i].children ? utils.getColumnCount(children[i]) : 1;
      }
      return count;
    },

    /**
     * 创建表格头部
     * @param {*} list 
     */
    createTableHeader(columns, headerTree) {
      headerTree = utils.setTreeSort(JSON.parse(JSON.stringify(headerTree)));
      const cols = utils.treeToList(headerTree)
      const fields = cols.filter(col => !col.hasChildren).sort((a, b) => a.sort - b.sort);
      const colgroup = utils.createColgroup(fields);
      const headerStr = columns.map(item => {
        const cols = item.map(col => `<th rowspan=${col.rowspan} colspan=${col.colspan}>${col.label}</th>`).join('');
        return `<tr>${cols}</tr>`
      }).join('');
      return `
        ${colgroup}
        <thead class="table-head">
          ${headerStr}
        </thead>
      `;
    },

    /**
     * 创建单元格组
     * @param {*} columns 
     * @returns 
     */
    createColgroup(columns) {
      const cols = columns.map(col => `<col name="${col.dataIndex}" />`).join('');
      return `<colgroup>${cols}</colgroup>`;
    },

    /**
     * 创建表体
     * @param {*} columns 
     * @param {*} data 
     */
    createTableBody(columns, data, cellMerge) {
      columns = columns || []
      data = data || []
      const colgroup = utils.createColgroup(columns);
      const bodyStr = data.map((tr, rowIdx) => {
        let tds = columns.map(td => {
          const { dataIndex } = td;
          const mergeInfo = cellMerge[dataIndex][rowIdx]
          // 存在合并，并且是合并的第一个；
          if (mergeInfo.rowspan > 1 && mergeInfo.rowspanIndex === 0) {
            return `<td data-index="${td.dataIndex}-${rowIdx}" rowspan="${mergeInfo.rowspan}">${typeof tr[td.dataIndex] === 'undefined' ? '' : tr[td.dataIndex]}</td>`
          }
          // 存在合并，但是不是合并的头部第一个，所以需要删除
          if (mergeInfo.rowspan === 1) {
            return `<td data-index="${td.dataIndex}-${rowIdx}">${typeof tr[td.dataIndex] === 'undefined' ? '' : tr[td.dataIndex]}</td>`;
          }
          return ''
        })
        let rowStr = `<tr>\n${tds.join('\n')}\n</tr>`;
        return rowStr
      }).join('\n')
      return `${colgroup}<tbody class="table-body">${bodyStr}</tbody>`;
    },

    /**
     * 渲染表格
     * @param {string} container 容器
     * @param {array} columns 字段列表
     * @param {array} data 数据
     * @returns 
     */
    renderTable(container, columns, headerTree) {
      columns = columns ? JSON.parse(JSON.stringify(columns)) : [];
      const tableContainer = typeof container === 'string' ? doc.querySelector(container) : container
      const header = utils.createTableHeader(columns, headerTree);
      tableContainer.querySelector('.my-table-header').innerHTML = header
      return {
        //设置数据
        renderBody: function (renderColumns, data, cellMerge) {
          const bodyStr = utils.createTableBody(renderColumns, data, cellMerge)
          tableContainer.querySelector('.my-table-body').innerHTML = bodyStr
        }
      }
    },

    /**
     * 获取表体字段列表
     * @param {*} columns : ;
     * @returns 
     */
    getBodyColumns(columns) {
      if (!columns) return []
      let result = [];
      let cacheKey = {};
      const _walk = function (d) {
        for (let i = 0, len = d.length; i < len; i++) {
          const item = d[i];
          if (item.colspan > 1 && item.children) {
            _walk(item.children);
          }
          if (item.colspan === 1 && !item.children && !cacheKey[item.key]) {
              cacheKey[item.key] = item;
              result.push(item);
          }
        }
      }
      _walk(columns)
      cacheKey = null;
      return result;
    },

    /**
     * 树形转为list
     * @param {array} tree 
     * @returns {array}
     */
    treeToList(tree) {
      let result = []; 
      let stack = tree;
      while (stack.length > 0) {
        const data = stack.shift();
        result.push(data)
        if (Array.isArray(data.children) && data.children.length > 0) {
          stack = stack.concat(data.children);
        }
      }
      return result;
    },

    /**
     * 元素自动滚动
     * @param {*} container 
     * @param {number} speed 速度
     * @param {boolean} isLoop 是否循环滚动
     * @returns 
     */
    createElementAutoScroll(container, { speed, isLoop }) {
      let timer = null;
      const SPEED = speed || 30;
      const element = typeof container === 'string' ? doc.querySelector(container) : container;
      const _clear = () => (timer && clearInterval(timer));
      const move = () => {
        _clear()
        element.scrollTop++;
        timer = setInterval(() => {
          element.scrollTop++;
          const { scrollTop, clientHeight, scrollHeight } = element;
          // 判断是否滚动到了底部
          if (scrollTop + clientHeight >= scrollHeight) {
            element.scrollTop = 0;
            // 是否循环滚动
            if (!isLoop) {
              _clear();
            }
          }
        }, SPEED);
      }

      // 绑定移入移出事件
      const bindHoverEvent = () => {
        element.addEventListener('mouseenter', () => {
          _clear();
        });
        element.addEventListener('mouseleave', () => {
          move();
        });
      }

      return {
        // 开始
        start() {
          move();
          bindHoverEvent();
        },
        // 暂停
        stop() {
          _clear();
        }
      }
    }
  }

  // export
  G.utils = G.utils || utils;
})(this, document);